using System;
using System.ComponentModel;
using MyUtils;
using NUnit.Framework;

namespace NotifiableLinqTests.FrameWork
{
	class ObjectListenerStragegy : IListenerStragegy
	{
		public Func<object> Expector { get; set; }

		object Expected { get { return Expector(); } }

		object _valueProviderSource;
		INotifyPropertyChanged _notifiableSource;
		public void InitializeListener(object queryResult)
		{
			_valueProviderSource = queryResult;
			_notifiableSource = (INotifyPropertyChanged)queryResult;
			_notifiableSource.PropertyChanged += QueryResult_PropertyChanged;
		}

		bool _atLeastOneNotified;
		object _lastNotifiedValue;

		void QueryResult_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			_atLeastOneNotified = true;
			Assert.IsTrue(ReferenceEquals(_notifiableSource, sender));
			Assert.IsTrue(string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Value");
			_lastNotifiedValue = GetValue(sender);
		}


		static object GetValue(object valueProvider)
		{
			return TargetValueProvider.GetValue(valueProvider);
		}

		public void PerformAssert()
		{
			var actual = GetValue(_valueProviderSource);
			Assert.AreEqual(Expected, actual);
			if (_atLeastOneNotified)
			{
				Assert.AreEqual(actual, _lastNotifiedValue);
			}
		}
	}
}